/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tamanho;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 *
 * @author gil
 */
public class DownloadFile {

    private String fullWebPath;
    private String localPath;
    private int size;
    private URL url;
    private boolean tipo;
    private String host;
    private String fileName;
    private String path;
    private boolean windows;

    DownloadFile(String url, String localpath) throws MalformedURLException {
        this.core(url, localpath);
    }

    private void core(String url, String localPath) throws MalformedURLException {

        /*
         * 1- recebe o url (string) e o localpath (string) local onde vai ser guardado o ficheiro 
         * 2- convert a string em url
         * 3- obtem o nome do ficheiro para fazer download
         * 4- full path na web
         * 5- tamanho do ficheiro
         * 6- host na web
         * 7- path local 
         */
        
        URL url1 = new URL(url);
        

        this.url = url1;
        
        // nome file
        this.setNomeFileHtml(url);

//full path na web
        this.setFullWebPath(url);

        //set do tamanho do ficheiro
        this.setSize();

        //set do host/site
        this.setHost();

        //set do local path
        this.setLocalPath(localPath + this.host);

        //verifica se é windows ou linux/mac
        this.setWindows(); //verifica se é windows
        
        
        //trata das backslash
        this.setBackSlashPath(url1);
////this.setLocalPath(this.getLocalPath()+this.path);


        //verificar se o tipo de ficheiro é html/etc
        this.fileType(url);


    }

    /*
     * verificar se o tipo de url é para ser processado pelo parser
     */
    public boolean isPagetoParser() {
        return this.tipo;

    }

    /*
     * retorna o nome do ficheiro do url, exemplo: index.html
     */
    private void setNomeFileHtml(String fileName) {

        this.fileName = new File(fileName).getName();
    }

    public String nomeFileHTML() {

        return this.fileName;
    }

    /*
     * verifica o tamanho do ficheiro do url em bytes (int)
     * no caso de endereço errado ou inexistente retorna -1
     */
    private int getFileSize() {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) this.url.openConnection();
            conn.setRequestMethod("HEAD");
            conn.getInputStream();
            return conn.getContentLength();
        } catch (IOException e) {
            return -1;
        } finally {
            conn.disconnect();
        }
    }

    /*
     * resultado -1 - falha ao obter ficheiro externo
     * resultado -2 - falha ao criar ficheiro local
     * resultado  1 - operação ok
     */
    public int downloadFile(String path, String urlString) {
        int resultado = 1;
        try {
            String tmp;
            tmp = path + nomeFileHTML();
            resultado = this.coreDownloadFile(tmp, urlString);
        } catch (MalformedURLException ex) {
            //      System.out.println("MalformedURLException");
            //        Logger.getLogger(downloadFile.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            //         System.out.println("IOException");
            //        Logger.getLogger(downloadFile.class.getName()).log(Level.SEVERE, null, ex);
        }

        return resultado;
    }

    private int coreDownloadFile(String filename, String urlString) throws MalformedURLException, IOException {

        BufferedInputStream in = null;
        FileOutputStream fout = null;
        try {


            //criar ligação externa

            try {

                in = new BufferedInputStream(new URL(urlString).openStream());
            } catch (IOException ex) {
                //    System.out.println("erro na criação do file");
                return -1;
            }

            //criação ficheiro local
            try {
                fout = new FileOutputStream(filename);
            } catch (IOException ex) {
                //    System.out.println("erro na criação do file");
                return -2;
            }

            byte data[] = new byte[1024];
            int count;
            while ((count = in.read(data, 0, 1024)) != -1) {
                fout.write(data, 0, count);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (fout != null) {
                fout.close();
            }
        }
        return 1;
    }

    /*
     * Este metodo verifica o contentType do ficheiro a descarregar 
     */
    private void fileType(String urlString) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();

        try {
            String mimeType = fileNameMap.getContentTypeFor(urlString);
            if (mimeType.equals("text/html")) {
                this.tipo = true;

            } else {
                this.tipo = false;

            }
        } catch (NullPointerException ex) {
           // System.out.println("\nerro");

        }
     
    }

    /*
     * retorna o path na web do url passado
     */
    public String getFullWebPath() {
        return this.fullWebPath;
    }

    /*
     * set do fullWebPath
     */
    private void setFullWebPath(String webPath) {

        this.fullWebPath = webPath;
    }

    /*
     * retorna o tamanho do ficheiro do url em bytes (int)
     * no caso de endereço errado ou inexistente retorna -1
     */
    public int getSize() {
        return size;
    }

    /*
     * set do tamanho do ficheiro do url
     */
    private void setSize() {
        this.size = this.getFileSize();
    }

    /*
     * retorna o path local criado
     */
    public String getLocalPath() {
        return this.localPath;
    }

    /*
     * retorna o host/site d url
     */
    public String getHost() {

        return this.host;
    }

    private void setHost() {
        this.host = this.url.getHost();
    }

    private void setLocalPath(String localPath) {
        this.localPath = localPath;
    }

    public String getPath() {
        return path;
    }

    //trata das back barras no path
    private void setBackSlashPath(URL path) {

        this.path = this.convertBarras(path.getPath().replaceAll(this.fileName, ""));

    }

    //substitui / por \ ou vice versa
    private String convertBarras(String str) {
        String tmp = null;
        if (str.contains("/") && this.isWindows()) {
            tmp = str.replace("/", "\\");
        } /*else if (str.contains("\\")) {
         tmp = str.replace("\\", "/");
         }*/
        else{
            tmp=str;
        }
        return tmp;

    }

    //verifica e trata das / e \ no windows 
    
    private boolean isWindows() {
        return windows;
    }

    private void setWindows() {
        if (this.localPath.contains("\\")) {
            this.windows = true;
        } else {
            this.windows = false;
        }

    }
}
